<?php
/**
 * Класс вспомогательных функций
 *
 * @author Александр Егоров <slamer@slamer.ru>
 * @author Дмитрий Кузьма <kouzma.d@slamer.ru>
 * @version 1.0
 */

class Service_Function {



	/**
	 * Обрабочтчик непойманных исключений
	 * Выводит информацию о необработанных исключениях
	 *
	 * @param Exception $exception - необработанное исключение
	 */
	public static function exceptionHandler(Exception $exception) {
	  if (SHOW_ERROR_MESSAGES) {
			echo '<div class="programmError">';
		  echo '<strong>Uncaught exception</strong><br />';
		    echo 'Message: ' . $exception->getMessage() . '<br />';
		    echo 'File: <strong>' . $exception->getFile() . '</strong>, string <strong>' . $exception->getLine() . '</strong><br />';
		    $arrExceptionTrace = $exception->getTrace();
		    if (sizeof($arrExceptionTrace)) {
		      echo 'Chain:<br />';
		      $size = sizeof($arrExceptionTrace);
		      for ($i = 0; $i < $size; $i++) {
		        echo '&nbsp;&nbsp;&nbsp;&nbsp;<strong>' . $arrExceptionTrace[$i]['file'] . '</strong>, string <strong>' . $arrExceptionTrace[$i]['line'] . '</strong>, function <strong>' . $arrExceptionTrace[$i]['function'] . '</strong>(';
		        //echo join(', ', $arrExceptionTrace[$i]['args']);
		        echo ')<br />';
		      }
		    }
		  echo '</div><br />';
		}
	  $logErrType = 3;
		$logMsg = date("Y-m-d H:i:s") . ' Uncaught exception of the file ' . $exception->getFile() . ' (' . $exception->getLine() . '): ' . $exception->getMessage() . "\n";
	  error_log($logMsg, $logErrType, str_replace('log', 'log_min', LOG));
	  error_log($logMsg, $logErrType, LOG);
	}

	/**
	 * Обработчик ошибок, предупреждений и пр.
	 * Выводит информацию о всевозможных ошибках
	 *
	 * @param integer $errType
	 * @param string $errMsg
	 * @param string $errFile
	 * @param integer $errLine
	 * @param array $errContext
	 */
	public static function errorHandler($errType, $errMsg, $errFile, $errLine, $errContext) {
	  switch ($errType) {
	    //E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING - эти ошибки нельзя обработать
	    case E_WARNING: case E_NOTICE: case E_CORE_WARNING: case E_USER_ERROR: case E_USER_WARNING: case E_USER_NOTICE: //Выводим все важные предупреждения в браузер, в лог-файл
				//$objSession = User_Session::instance();
				//$userID = $objSession->getUserId();
				if (SHOW_ERROR_MESSAGES) {
					echo '<div class="programmError">';
		  	  echo '<strong>' . self::getExcteptionTypeName($errType) . '</strong><br />';
			    echo 'Message: ' . $errMsg . '<br />';
			    echo 'File: <strong>' . $errFile . '</strong>, String <strong>' . $errLine . '</strong><br />';
				  echo '</div><br />';
				}
		  case (E_NOTICE | E_USER_NOTICE):
	    default: //Выводим определенные и оставшиеся ошибки в лог-файл
	    	$logMsg = date("Y-m-d H:i:s") . ' Error ' . $errType . ' in the file ' . $errFile . ' (' . $errLine . '): ' . $errMsg . "\n";
	    	$logMsg .= print_r($errContext, true);
	    	$arrFullDebug = debug_backtrace();
	    	$arrDebug[] = $arrFullDebug[1];
	    	if (isset($arrFullDebug[2])) $arrDebug[] = $arrFullDebug[2];
	    	if (isset($arrDebug[1]['object'])) $arrDebug[1]['object'] = get_class($arrDebug[1]['object']);
	    	if (isset($arrDebug[0]['object'])) $arrDebug[0]['object'] = get_class($arrDebug[0]['object']);
	    	$logErrType = 3;
	    	error_log($logMsg, $logErrType, str_replace('log', 'log_min', LOG));
	    	$logMsg .= print_r($arrDebug, true);
	    	$logMsg .= "----------------------------------------------------------------------------------------------\n";
	      error_log($logMsg, $logErrType, LOG);
		}
	}
	
	/**
	 * Определяет склонение слов в зависимсти от количества
	 * 
	 * @param integer $count - количество, string $skl1, $skl2, $skl3 - склонения
	 * @return string $skl - слово в нужном склонении
	 */
	public static function getDeclination ($count, $skl1, $skl2, $skl3) {
		$count = $count . '';
		if ($count[strlen($count)-1] == '1') $skl = $skl1;
		elseif (strstr('2 3 4', $count[strlen($count)-1])) $skl = $skl2;
		else $skl = $skl3;
		return $skl;
	}

	
	/**
	 * Выдает текстовое представление типа ошибки по его числовому эквиваленту
	 *
	 * @param integer $errType - числовой тип ошибки
	 * @return string - строковый тип ошибки
	 */
	public static function getExcteptionTypeName($errType) {
	  switch ($errType) {
	    case 1: return 'FATAL ERROR';
	    case 2: return 'WARNING';
	    case 4: return 'PARSE';
	    case 8: return 'NOTICE';
	    case 16: return 'CORE_ERROR';
	    case 32: return 'CORE_WARNING';
	    case 64: return 'COMPILE_ERROR';
	    case 128: return 'COMPILE_WARNING';
	    case 256: return 'USER_ERROR';
	    case 512: return 'USER_WARNING';
	    case 1024: return 'USER_NOTICE';
	    case 2048: return 'STRICT';
	  }
	}
	
	/**
	 * Преобразует строку из одной кодировки в другую
	 *
	 * @param string $str - строка для преобразования
	 * @param string $from - исходная кодировка строки
	 * @param string $to - выходная кодировка строки
	 * @return string - перекодированная строка
	 */
	public static function myConvertCharset($str, $from, $to) {
	  if (@function_exists('iconv')) {
	  	return iconv($from, $to, $str);
	  }
	  elseif (@function_exists('recode_string')) {
			return recode_string($from . '..'  . $to, $str);
	  }
	  else {
			print "function iconv not exists";
	    return $str;
	  }
	}

	/**
	 * Метод преобразует строку к нижнему регистру
	 *
	 * @param string $s
	 * @return string
	 */
	public static function strtolowerU($s) {
		//$t = "windows-1251";
		//$d = "utf-8";
		//return myConvertCharset(strtolower(myConvertCharset($s, $d, $t)), $t, $d);
		if (!$s) return $s;
	  return mb_strtolower($s, "utf-8");
	}

	/**
	 * Возвращает строку запроса url
	 *
	 * @return string - строка запроса
	 */
  public static function getCurrentUrl() {
		global $QUERY_STRING;
		global $PHP_SELF;
		if ($QUERY_STRING != '') return $PHP_SELF  . '?' . $QUERY_STRING;
		else return $PHP_SELF;
	}

	/**
	 * Возвращает строку запроса url, но без части идущей за знаком "?"
	 *
	 * @return string
	 */
	public static function getCurrentSmallUrl() {
		global $PHP_SELF;
		return Service_Escape::absolutelyEscapeString($PHP_SELF);
	}

	/**
	 * Получает то что находится в cuttext строки (cuttext="..." - возвращает ...)
	 *
	 * @param string $content - строка для поиска
	 * @param string $paramName - не используется
	 * @return string
	 */
	public static function getUniqueTextParamFirst($content, $paramName) {
	    $paramStartPos = strpos($content, 'cuttext="') + 9;
	    $paramEndPos = strpos($content, '"', $paramStartPos);
	    if (is_integer($paramStartPos) && is_integer($paramEndPos)) return substr($content, $paramStartPos, $paramEndPos - $paramStartPos);
	    else return '';
	}
	
	/**
	 * Метод возвращает содержимое некоторого HTML тега
	 *
	 * @param string $str - строка для поиска
	 * @param string $tag - искомый тег
	 * @return string
	 */
	public static function getTagBetweenValueFirst($str, $tag) {
	  $start = strpos($str, $tag);
	  $finish = self::findEndOfTag($str, $tag, $start);
	  $str = substr($str, $start - 1, ($finish - $start) + 2);
	  $str = substr($str, strpos($str, ">") + 1);
	  return substr($str, 0, strlen($str) - strlen('</' . $tag . '>'));
	}

	/**
	 * Получает длину строки с учетом того, что некоторые символы занимают 2 байта
	 *
	 * @param string $s
	 * @return int
	 */
	public static function utf8_strlen($s) {
    return preg_match_all('/./u', $s, $tmp);
	}

	/**
	 * Возвращает подстроку с учетом тго, что в utf8  некоторые символы занимают 2 байта
	 *
	 * @param string $s
	 * @param int $offset
	 * @param int $len
	 * @return string
	 */
	public static function utf8_substr($s, $offset, $len = 'all') {
    if ($offset < 0) $offset = self::utf8_strlen($s) + $offset;
    if ($len != 'all') {
      if ($len < 0) $len = self::utf8_strlen($s) - $offset + $len;
      $xlen = self::utf8_strlen($s) - $offset;
      $len = ($len>$xlen) ? $xlen : $len;
      preg_match('/^.{' . $offset . '}(.{0,'.$len.'})/us', $s, $tmp);
    }
    else {
      preg_match('/^.{' . $offset . '}(.*)/us', $s, $tmp);
    }
    return (isset($tmp[1])) ? $tmp[1] : false;
	}
	
	/**
	 * Метод находин конец тега, с учетом вложенности
	 *
	 * @param string $htmlString
	 * @param string $tagName
	 * @param integer $startPosition
	 */
	public static function findEndOfTag($htmlString, $tagName, $startPosition, $k = 1) {
		$tagNameLength = strlen($tagName);
		$closePosition = $openPosition = $startPosition;
		for (; $k > 0; $k--) {
			$closePosition = strpos( $htmlString, '</' . $tagName, $closePosition);
			if ($closePosition === false) return false;
			$closePosition = strpos( $htmlString, '>', $closePosition);
		}
		while (true) {
			$openPosition = strpos( $htmlString, '<' . $tagName, $openPosition);
			if ($openPosition === false) break;
			$openPosition = strpos( $htmlString, '>', $openPosition);
			if ($openPosition < $closePosition) $k++;
			else break;
		  if ($k == 100) break;
		}

		if ($k == 0) return $closePosition;
		else return self::findEndOfTag($htmlString, $tagName, $closePosition + 1, $k);
	}

	/**
	 * Метод возвращает подстроку с троеточием на конце, если длина исходной строки меньше подстроки. В противном случае возвращает исходную строку
	 *
	 * @param string $str
	 * @param int $limit
	 * @return string
	 */
	public static function utf8_string_with_limit($str, $limit, $bySpace = false) {
		if (self::utf8_strlen($str) <= $limit + 1) return $str;
		else {
			if ($bySpace) {
			  $str = self::utf8_substr($str, 0, $limit + 1);
	      do {
	        $sym = self::utf8_substr($str, -1, 1);
	        $str = self::utf8_substr($str, 0, self::utf8_strlen($str) - 1);
	      } while ($sym != ' ' && self::utf8_strlen($str) > 10);
	      $str .= '...';
	      return $str;	    
			} 
			else return self::utf8_substr($str, 0, $limit) . '...';
		}
	}

	/**
	 * Возвращает строку с заглавной перовой буквой с учетом того, что в utf8  некоторые символы занимают 2 байта
	 *
	 * @param string $s
	 * @param int $offset
	 * @param int $len
	 * @return string
	 */
	public static function utf8_first_to_upper($s) {
		$first = self::utf8_substr($s, 0, 1);
		$last = self::utf8_substr($s, 1);
    return mb_strtoupper($first, "utf-8") . $last;
	}
	/**
	 * Возвращает строку со строчной перовой буквой с учетом того, что в utf8  некоторые символы занимают 2 байта
	 *
	 * @param string $s
	 * @param int $offset
	 * @param int $len
	 * @return string
	 */
	public static function utf8_first_to_lower($s) {
		$first = self::utf8_substr($s, 0, 1);
		$last = self::utf8_substr($s, 1);
    return mb_strtolower($first, "utf-8") . $last;
	}

	/**
	 * Метод возвращает часть HTML кода, закрывая открытые теги
	 *
	 * @param string $textWithHtml
	 * @param integer $limitOfNoneHtml
	 * @return string
	 */
	public static function getPartOfHtmlText($textWithHtml, $limitOfNoneHtml = 250) {
		if (self::utf8_strlen($textWithHtml) <= $limitOfNoneHtml) return $textWithHtml;
		$currentTextLength = 0;
		$retText  = '';
		$openTagPos = strpos($textWithHtml, '<');
		$closeTagPos = -1;
		if ($openTagPos === false) return $textWithHtml; // Если это голый текст без html
		while ($openTagPos !== false) {
			if ($openTagPos > $closeTagPos + 1) {
				$partOfText = substr($textWithHtml, $closeTagPos + 1, $openTagPos - $closeTagPos - 1);
				$partOfTextLength = self::utf8_strlen($partOfText);
				if ($currentTextLength + $partOfTextLength < $limitOfNoneHtml) {
					$currentTextLength += $partOfTextLength;
					$tagSpacePos = strpos($textWithHtml, ' ', $openTagPos);
				}
				else { // Дошли до нужного количества символов
					$retText = substr($textWithHtml, 0, $closeTagPos + 1);
					$partOfText = self::utf8_substr($textWithHtml, $closeTagPos + 1, $limitOfNoneHtml - $currentTextLength);
					$firstSpaceBeforeEnd = strrpos($partOfText, ' ');
					$retText .= substr($partOfText, 0, $firstSpaceBeforeEnd);
					return $retText;
				}
			}
			$closeTagPos = strpos($textWithHtml, '>', $openTagPos);
			if ($closeTagPos === false) return $textWithHtml; // Один из тегов не закрыт
			$openTagPos = strpos($textWithHtml, '>', $closeTagPos);
		}
		$retText = substr($textWithHtml, 0, $closeTagPos + 1);
		$partOfText = self::utf8_substr($textWithHtml, $closeTagPos + 1, $limitOfNoneHtml - $currentTextLength);
		$firstSpaceBeforeEnd = strrpos($partOfText, ' ');
		$retText .= substr($partOfText, 0, $firstSpaceBeforeEnd);
		return $retText;
	}

	/**
	 * Метод закрывает открытые html-теги
	 *
	 * @param string $textWithHtml
	 * @return string
	 */
	public static function closetags($text)	{
		// Выбираем абсолютно все теги
	 	if (preg_match_all("/<([\/]?)([\w\d]+)[^>\/]*>/iU", $text, $matches, PREG_SET_ORDER)) {
	  	$stack = array();
	  	foreach ($matches as $k => $match) {
	   		$tag = strtolower($match[2]);
	   		if (!$match[1]) {
	    		// если тег открывается добавляем в стек
	    		$stack[] = $tag;
	   		}
	   		elseif (end($stack) == $tag) {
	    		// если тег закрывается, удаляем из стека
	    		array_pop($stack);
	   		}
	   		else {
	    		// если это закрывающий тег, который не открыт, открываем
	    		$text = '<' . $tag . '>' . $text;
	   		}
	  	}
	  	while ($tag = array_pop($stack)) {
	  		// закрываем все открытые теги
	   		$text .= '</' . $tag . '>';
	  	}
	 	}
	 	return $text;
	}

	public static function replaceQuotes($str) {
	  return str_replace("'", "&#39;", str_replace("\"", "&quot;", $str));
	}

  public static function strlenUnicode($str) {
    return strlen(iconv("UTF-8", "WINDOWS-1251", $str));
  }

  /**
   * Обрезает строку по последему пробелу и дописывает многоточие
   *
   * @return string
   */
  public static function cutString($str, $charAmount) {
    $str = iconv("UTF-8", "WINDOWS-1251", $str);
    if (strlen($str) > $charAmount) {
      $str = substr($str, 0, $charAmount+1);
      do {
        $sym = substr($str, -1, 1);
        $str = substr($str, 0, strlen($str)-1);
      } while ($sym != ' ' && strlen($str) > 10);
      $str .= '...';
    }
    $str = iconv("WINDOWS-1251", "UTF-8", $str);
    return $str;
  }

  /**
   * Обрезает строку по последему пробелу и дописывает многоточие
   *
   * @return string
   */
  public static function getUrlWithGetParamsByArray($url, $arrParams) {
  	$i = 0;
  	$params = '';
		foreach($arrParams as $var => $val) {
			if ($i++) $params .= '&';
			$params .= $var . '=' . $val;
		}
		return $url . '?' . $params;
  }

  /**
   * Получаем куки FaceBook
   * @param  $app_id
   * @param  $application_secret
   */
	public static function getFacebookCookie($app_id, $application_secret) {
		if (isset($_COOKIE['fbs_' . $app_id])) {
			$args = array();
		  parse_str(trim($_COOKIE['fbs_' . $app_id], '\\"'), $args);
		  ksort($args);
		  $payload = '';
		  foreach ($args as $key => $value) {
		    if ($key != 'sig') {
		      $payload .= $key . '=' . $value;
		    }
		  }
		  if (md5($payload . $application_secret) != $args['sig']) {
		    return null;
		  }
		  setcookie('fbs_' . $app_id, null, -1, W_ABSPATH);
		  return $args;
		}
		else return array();
	}
	
	/**
	 * Определяем приход бота
	 * @return bool - если бот то true
	 */
  public static function spiderDetect() {
    $engines = array(
      array('Aport', 'Aport robot'),
      array('Google', 'Google'),
      array('msnbot', 'MSN'),
      array('Rambler', 'Rambler'),
      array('Yahoo', 'Yahoo'),
      array('AbachoBOT', 'AbachoBOT'),
      array('accoona', 'Accoona'),
      array('AcoiRobot', 'AcoiRobot'),
      array('ASPSeek', 'ASPSeek'),
      array('CrocCrawler', 'CrocCrawler'),
      array('Dumbot', 'Dumbot'),
      array('FAST-WebCrawler', 'FAST-WebCrawler'),
      array('GeonaBot', 'GeonaBot'),
      array('Gigabot', 'Gigabot'),
      array('Lycos', 'Lycos spider'),
      array('MSRBOT', 'MSRBOT'),
      array('Scooter', 'Altavista robot'),
      array('AltaVista', 'Altavista robot'),
      array('WebAlta', 'WebAlta'),
      array('IDBot', 'ID-Search Bot'),
      array('eStyle', 'eStyle Bot'),
      array('Mail.Ru', 'Mail.Ru Bot'),
      array('Scrubby', 'Scrubby robot'),
      array('Yandex', 'Yandex'),
      array('YaDirectBot', 'Yandex Direct')
    );
    foreach ($engines as $engine) {
      if (strstr($_SERVER['HTTP_USER_AGENT'], $engine[0])) {
        return($engine[1]);
      }
    }
    return false;
  }

  /**
   * Определяем номер символа в кодировке utf-8
   * 
   * @param $c - символ
   */
	public static function uniord($c) {
		if (empty($c)) return false;
    $h = ord($c{0});
    if ($h <= 0x7F) return $h;
    else if ($h < 0xC2) return false;
    else if ($h <= 0xDF)return ($h & 0x1F) << 6 | (ord($c{1}) & 0x3F);
    else if ($h <= 0xEF) return ($h & 0x0F) << 12 | (ord($c{1}) & 0x3F) << 6 | (ord($c{2}) & 0x3F);
    else if ($h <= 0xF4) {
        return ($h & 0x0F) << 18 | (ord($c{1}) & 0x3F) << 12
                                 | (ord($c{2}) & 0x3F) << 6
                                 | (ord($c{3}) & 0x3F);
    } 
    else return false;
	}

	/**
	 * Удаляем куки (в том числе и многомерные)
	 * 
	 * @param string $cookie - ключ в массиве для удаления
	 * @param array $arr - массив с которым работаем (по умолчанию $_COOKIE)
	 * @param string $string - строка формирущаяся для удаления многомерных кук
	 */
	public static function unsetCookie($cookie, $arr = array(), $string = '') {
		Service_Debug::setDebug();
		$arr = empty($arr) ? $_COOKIE : $arr;
		if (!isset($arr[$cookie])) return false;
		if (is_array($arr[$cookie]))  {
			foreach ($arr[$cookie] as $key => $value) {
				self::unsetCookie($key, $arr[$cookie], $string . (empty($string) ? $cookie : '') . '[' . $key . ']');
			}			
		}
		else setcookie(($string ? str_replace(array('[', ']'), array('%5B', '%5D'), $string) : $cookie), null, time() - 3600, W_ABSPATH);
		
	}
	
	
	/**
	 * Проверка карты на валидность
	 * @param cn - номер карты
	 * @returns {Boolean} - true - валидна
	 */
	public static function validateCard($cn){
		$odd = array();
		$even = array();
	  for ($x = 0; $x < strlen($cn); $x++) {
	  	if ($x % 2 == 0) $odd[] = $cn[$x];
	    else $even[] = $cn[$x];
		}
	  foreach ($odd as $x => $value) {
	  	$tmp = $odd[$x] * 2;
	    if ($tmp <= 9) $odd[$x] = $tmp;
    	else {
	      $s = (string)$tmp;
	      $odd[$x] = $s[0] + $s[1];
	    }
		}
		$summa = 0;
		foreach ($odd as $value) {
			$summa += $value;
		}
		foreach ($even as $value) {
			$summa += $value;
		}
		if ($summa % 10 == 0) return true;
		else return false;
	}

	/**
	 * Возвращает значение в массиве если оно есть, иначе возвращает default
	 * 
	 * @param array $arrIn - входной массив 
	 * @param mixed $default - значение по умолчанию
	 * @param $key mixed - ключ массива 
	 * @param _ mixed[optional] - доп.ключи массива 
	 * 
	 * @throws Exception
	 * @return string
	 */
	public static function getValue($default, $arrIn, $key) {
		Service_Debug::setDebug();
		$size = func_num_args(); 
		if ($size < 3) throw new Exception('Не хватает параметров');
		$arrKeys = func_get_args();
		for ($i = 2; $i < $size; $i++) {
			if (isset($arrIn[$arrKeys[$i]])) $arrIn = $arrIn[$arrKeys[$i]];
			else return $default;
		}
		return $arrIn;
	}

	/**
	 * Расстояние между двумя точками
	 * $latA, $longA - широта, долгота 1-й точки,
	 * $latB, $longB - широта, долгота 2-й точки
	 * Написано по мотивам http://gis-lab.info/qa/great-circles.html
	 * Михаил Кобзарев <kobzarev@inforos.ru>
	 *
	 */
	public static function calculateTheDistance($latA, $longA, $latB, $longB) {
		Service_Debug::setDebug();
		$earthRadius = 6372795;
    // перевести координаты в радианы
    $lat1 = $latA * M_PI / 180;
    $lat2 = $latB * M_PI / 180;
    $long1 = $longA * M_PI / 180;
    $long2 = $longB * M_PI / 180;

    // косинусы и синусы широт и разницы долгот
    $cl1 = cos($lat1);
    $cl2 = cos($lat2);
    $sl1 = sin($lat1);
    $sl2 = sin($lat2);
    $delta = $long2 - $long1;
    $cdelta = cos($delta);
    $sdelta = sin($delta);

    // вычисления длины большого круга
    $y = sqrt(pow($cl2 * $sdelta, 2) + pow($cl1 * $sl2 - $sl1 * $cl2 * $cdelta, 2));
    $x = $sl1 * $sl2 + $cl1 * $cl2 * $cdelta;

    //
    $ad = atan2($y, $x);
    $dist = $ad * $earthRadius;

    return $dist;
	}
	
	public static function changeLayot($text, $layot) {
		Service_Debug::setDebug();
		$arrRus = array(
	  "й","ц","у","к","е","н","г","ш","щ","з","х","ъ",
	  "ф","ы","в","а","п","р","о","л","д","ж","э",
	  "я","ч","с","м","и","т","ь","б","ю",
	  "Й","Ц","У","К","Е","Н","Г","Ш","Щ","З","Х","Х",
	  "Ф","Ы","В","А","П","Р","О","Л","Д","Ж","Э",
	  "Я","Ч","С","М","И","Т","Ь","Б","Ю",
	  );
	  $arrEng = array(
	  "q","w","e","r","t","y","u","i","o","p","[","]",
	  "a","s","d","f","g","h","j","k","l",";","'",
	  "z","x","c","v","b","n","m",",",".",
	  "Q","W","E","R","T","Y","U","I","O","P","{","}",
	  "A","S","D","F","G","H","J","K","L",":",'"',
	  "Z","X","C","V","B","N","M","<",">",
	  );
	  if ($layot == 'en') return str_replace($arrRus, $arrEng, $text);	
	  if ($layot == 'ru') return str_replace($arrEng, $arrRus, $text);	
	}
	
	public static function getPrintArray($arrIn, $depth = 0) {
		Service_Debug::setDebug();
		$text = '';
		if ($depth) {
			for ($i = 0; $i < $depth; $i++) $text .= '&nbsp;';
			$text .= '---<br />';
		}
		foreach ($arrIn as $key => $value) {
			if (is_array($value)) {
				$text .= self::getPrintArray($value, $depth + 1);
			}
			else {
				for ($i = 0; $i < $depth; $i++) $text .= '&nbsp;';
    		$text .= str_replace('_', ' ', Service_Function::utf8_first_to_upper($key));
    		$text .= ': ' . $value . '<br />';
			}
    }
		if ($depth) {
			for ($i = 0; $i < $depth; $i++) $text .= '&nbsp;';
			$text .= '---<br />';
		}
    
    
    return $text;
	}
}
?>